/***********************************************************************************
*	File: Game.cpp
*	Author: Keisuke Miyazaki
*	Project: Mari's Flower
*	Date: 09/13/2013
***********************************************************************************/
#include "Game.h"

#include <ctime>
#include "../SGD Wrappers/CSGD_Direct3D.h"
#include "../SGD Wrappers/CSGD_DirectInput.h"
#include "../SGD Wrappers/CSGD_TextureManager.h"
#include "../SGD Wrappers/CSGD_XAudio2.h"

#include "GameStates/MainMenuState.h"

#define Black	D3DCOLOR_XRGB( 0, 0, 0 )

CGame* CGame::s_pInstance = nullptr;

CGame* CGame::GetInstance( void )
{
	if( s_pInstance == nullptr )
		s_pInstance = new CGame;

	return s_pInstance;
}
void CGame::DeleteInstance( void )
{
	delete s_pInstance;
	s_pInstance = nullptr;
}

CGame::CGame(void)
{
	m_eLanguage		= ENGLISH;
	m_pD3D			= nullptr;
	m_pDI			= nullptr;
	m_pTM			= nullptr;
	m_pXA			= nullptr;

	m_nScreenWidth	= 1;
	m_nScreenHeight	= 1;
	m_bIsWindowed	= true;
	m_bInGame		= false;

	m_pCurrentState = nullptr;

	m_dwCurrTime	= 0;

	srand( (unsigned int)time( nullptr ) );
}

void CGame::Initialize( HWND hWnd, HINSTANCE hInstance, int nWidth, int nHeight, bool bIsWindowed )
{
	m_pD3D			= CSGD_Direct3D::GetInstance();
	m_pDI			= CSGD_DirectInput::GetInstance();
	m_pTM			= CSGD_TextureManager::GetInstance();
	m_pXA			= CSGD_XAudio2::GetInstance();
	m_nScreenWidth	= nWidth;
	m_nScreenHeight	= nHeight;
	m_bIsWindowed	= bIsWindowed;

	m_pD3D->Initialize( hWnd, m_nScreenWidth, m_nScreenHeight, m_bIsWindowed, false );
	m_pDI->Initialize( hWnd, hInstance, DI_KEYBOARD | DI_MOUSE /*| DI_JOYSTICKS*/ );
	m_pTM->Initialize( m_pD3D->GetDirect3DDevice(),	m_pD3D->GetSprite() );
	m_pXA->Initialize();

	ChangeState( CMainMenuState::GetInstance() );

	m_dwCurrTime	= GetTickCount();
}

bool CGame::Status( void )
{
	if( Input() == false )
		return false;

	Update();
	Render();

	return true;
}

void CGame::Terminate( void )
{
	ChangeState( nullptr );

#pragma region Terminate SGD Wrappers
	m_pXA->Terminate();
	m_pTM->Terminate();
	m_pDI->Terminate();
	m_pD3D->Terminate();
#pragma endregion
#pragma region Reset Data Members
	m_pD3D			= nullptr;
	m_pDI			= nullptr;
	m_pTM			= nullptr;
	m_pXA			= nullptr;

	m_nScreenWidth	= 1;
	m_nScreenHeight	= 1;
	m_bIsWindowed	= true;
	m_bInGame		= false;
#pragma endregion

	m_dwCurrTime = 0;
}

void CGame::ChangeState( IGameState* pState )
{
	if( m_pCurrentState != nullptr )
		m_pCurrentState->Exit();

	m_pCurrentState = pState;

	if( m_pCurrentState != nullptr )
		m_pCurrentState->Enter();
}
void CGame::SwapState( IGameState* pState )
{
	m_pCurrentState = pState;
}

bool CGame::Input( void )
{
	m_pDI->ReadDevices();

	if(m_pDI->KeyDown(DIK_LMENU) == true || m_pDI->KeyDown(DIK_RMENU) == true)
	{
		if(m_pDI->KeyPressed(DIK_RETURN) == true)
			if (m_bIsWindowed == true)
			{
				CSGD_Direct3D::GetInstance()->Resize( GetScreenWidth(), GetScreenHeight(), false);
				m_bIsWindowed = false;
				return true;
			}
			else
			{
				CSGD_Direct3D::GetInstance()->Resize( GetScreenWidth(), GetScreenHeight(), true);
				m_bIsWindowed = true;
				return true;
			}
	}

	return m_pCurrentState->Input();
}

void CGame::Update( void )
{
	DWORD dwNow = GetTickCount();
	float fElapsedTime = (dwNow - m_dwCurrTime) / 1000.0f;
	m_dwCurrTime = dwNow;

	if( fElapsedTime > 0.125f )
		fElapsedTime = 0.125f;

	m_pCurrentState->Update( fElapsedTime );
}

void CGame::Render( void )
{
	m_pD3D->Clear(Black);

	m_pD3D->DeviceBegin();
	m_pD3D->SpriteBegin();

	m_pCurrentState->Render();

	m_pD3D->SpriteEnd();
	m_pD3D->DeviceEnd();

	m_pD3D->Present();
}
	